package commons.base.serialization.xml.example;

import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;

import commons.base.serialization.json.JsonExample.ErrorResponse;
import commons.base.serialization.xml.DateAdapter;
import commons.base.serialization.xml.Jaxb;
import commons.base.serialization.xml.XmlInit;

public class JaxbExample {

	public static void main(String[] args) throws Exception{
		t3();
	}
	
	public static void t1()throws Exception{
		System.err.println(Jaxb.toXML(new User()));
		
		String xml = readXml("error_response.xml");
		System.err.println(xml.startsWith("<error_response>"));
		User user = Jaxb.parse(User.class, readXml("jaxb.xml"));
		
		System.err.println(user.getAge() + ", " + Thread.currentThread());
		System.err.println(user.getBirthday());
		
//		UserBuyerGetResponse response = parseObject("", "user_buyer_get_response", UserBuyerGetResponse.class);
	}
	
	private static String readXml(String name) throws Exception{
		Path path = Paths.get(JaxbExample.class.getResource("/" + name).toURI());
		
		return new String(Files.readAllBytes(path), "UTF-8");
	}
	
	// or parseArray List<T>
	public static <T> T parseObject(String text, String fieldName, Class<T> clazz){
		text = text.trim();
		if(text.startsWith("<error_response>")){
			ErrorResponse errorResponse = Jaxb.parse(ErrorResponse.class, text);
			throw new RuntimeException("error: " + errorResponse.toString());
		}
		
		if(text.startsWith("<"+fieldName+">")){
			return Jaxb.parse(clazz, text);
		}
		
		throw new RuntimeException("illegal response: expect "+fieldName+" but " + text);
	}

	public static void t2()throws Exception{
		UserBuyerResponse.User user = new UserBuyerResponse.User();
		user.setAvatar("11");
		user.setNick("sss");
		user.setSex("m");
		
		UserBuyerResponse response = new UserBuyerResponse();
		response.getUserList().add(user);
		response.getUserList().add(user);
		
		System.err.println(Jaxb.toXML(response));		
	}
	
	public static void t3()throws Exception{
		long start = System.currentTimeMillis();
		UserBuyerResponse users = Jaxb.parse(UserBuyerResponse.class, readXml("user.xml"));
		long end = System.currentTimeMillis();
		
		System.err.println(end - start);
		
		System.err.println(users.getUserList().size());
		
	}
}

//@XmlRootElement(name="user")
class User{
	@XmlAttribute(name="sex")
	private String sex="man";
	
	@XmlAttribute
	private int age=20;
	
	@XmlElement(name="birthday")
	private String birthday="wang";
	
	@XmlElementWrapper(name="addresses")
	@XmlElement(name="address")
	private List<String> addresses = new ArrayList<String>();
	
	@XmlElementWrapper(name="stus")
	@XmlElement(name="stu") 
	private List<Stu> stus = new ArrayList<Stu>();
	
	@XmlJavaTypeAdapter(DateAdapter.class)
	private Date date = new Date();

	public User() {
		super();
		addresses.add("111");
		addresses.add("222");
		stus.add(new Stu(1, "zhang"));
		stus.add(new Stu(2, "li"));
	}

	public User(String sex, int age, String birthday) {
		super();
		this.sex = sex;
		this.age = age;
		this.birthday = birthday;
	}
	
	@XmlInit
	public void init(){
		System.err.println("init ..." + Thread.currentThread());
	}
	
	public String getSex() {
		return sex;
	}

//	public void setSex(String sex) {
//		this.sex = sex;
//	}

	public int getAge() {
		return age;
	}

//	public void setAge(int age) {
//		this.age = age;
//	}

	public String getBirthday() {
		return birthday;
	}

//	public void setBirthday(String birthday) {
//		this.birthday = birthday;
//	}

//	@XmlList
	public List<String> getAddresses() {
		return addresses;
	}

//	public void setAddresses(List<String> addresses) {
//		this.addresses = addresses;
//	}

	public Date getDate() {
		return date;
	}

//	public void setDate(Date date) {
//		this.date = date;
//	}
	
	public List<Stu> getStus() {
		return stus;
	}

//	public void setStus(List<Stu> stus) {
//		this.stus = stus;
//	}

	public static class Stu{
		@XmlElement(name="id")
		private int id;
		
		@XmlElement(name="name")
		private String name;
		
		public Stu(int id, String name) {
			super();
			this.id = id;
			this.name = name;
		}
		
		public Stu() {
			super();
		}

		public int getId() {
			return id;
		}
		
		public String getName() {
			return name;
		}
		
	}

}
